package com.plian.system.pdf;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.plian.Tools.StringUtil;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author wenyibo
 * @date 2019/10/14
 */
public class OutPdf {
	private static final Logger log = LoggerFactory.getLogger(OutPdf.class);
	public static <T> Map<String, Object> beanToMap(T bean) {
		if (bean == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(bean.getClass());
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (false == "class".equals(key)) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(bean);
					if (null != value) {
						map.put(key, value);
					}
				}
			}
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return map;
	}
	public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws IntrospectionException{
		return Introspector.getBeanInfo(clazz).getPropertyDescriptors();
	}
	/**
	 * 待加入图片的文字域,设置为隐藏;不然会遮挡掉图片的
	 * @param form
	 * @param pdfStamper
	 * @param imgAttr
	 * @param imgPath
	 * @throws DocumentException
	 * @throws IOException
	 */
	public static void insertImage(AcroFields form, PdfStamper pdfStamper, String imgAttr, String imgPath) throws DocumentException, IOException {
	    /**
	     * 添加图片
	     */
		List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions(imgAttr);
	    if (fieldPositions!=null&&fieldPositions.size()>0) {
			int page = fieldPositions.get(0).page;
			Rectangle signReact = fieldPositions.get(0).position;
			float height = signReact.getHeight();
			float width = signReact.getWidth();
			float x = signReact.getLeft();
			float y = signReact.getBottom();
			Image image = Image.getInstance(imgPath);
			float imageHeight = image.getHeight();
			float imageWidth = image.getWidth();
			imageHeight *= (width / imageWidth);
			PdfContentByte under = pdfStamper.getOverContent(page);
			image.scaleToFit(signReact.getWidth(), signReact.getHeight());
			image.setAbsolutePosition(x, y + (height - imageHeight) / 2);
			under.addImage(image);
		}
	}
	/**
	 * 日期转str
	 * @param date 日期
	 * @return  Map<String, Object>
	 */
	public static String processDate(Date date){
		SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
		return date==null?"":format.format(date);
	}
	/**
	 * 输出pdf
	 * @param bean 对象
	 * @param model 模板文件
	 * @param images 图片
	 * @return  File
	 */
	public File buildpdf(T bean, File model, Map< String,String > images) {
		File file = null ;
		try {
			if (bean!=null&&model.exists()) {
				Map< String,Object > data = beanToMap(bean);
				String fileName = model.getPath();
				PdfReader reader = new PdfReader(fileName);
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				/* 将要生成的目标PDF文件名称 */
				PdfStamper ps = new PdfStamper(reader, bos);
				/* 使用中文字体 */
				BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
				ArrayList<BaseFont> fontList = new ArrayList <> ();
				fontList.add(bf);

				/* 取出报表模板中的所有字段 */
				AcroFields fields = ps.getAcroFields();
				fields.setSubstitutionFonts(fontList);
				for (String key: data.keySet()) {
					if (data.get(key)!=null) {
						String value = data.get(key).toString();
						if (data.get(key) instanceof Date) {
							value = processDate((Date) data.get(key));
						}
						fields.setField(key, value);
					}
				}
				if (images!=null) {
					for (String key : images.keySet()) {
						if (!StringUtil.isEmpty(images.get(key))) {
							//待加入图片的文字域,设置为隐藏;不然会遮挡掉图片的
							insertImage(fields, ps, key, images.get(key));
						}
					}
				}
				/* 必须要调用这个，否则文档不会生成的 */
				ps.setFormFlattening(true);
				ps.close();
				File dir = new File(model.getParent());
				String classFullName = bean.getClass().getName();
				file = File.createTempFile(classFullName.substring(classFullName.lastIndexOf(".")), ".pdf", dir);
				OutputStream fos = new FileOutputStream(file);
				fos.write(bos.toByteArray());
				fos.flush();
				fos.close();
				bos.close();
			}

		} catch(Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return file;
	}

	public static File createPdf(File model, Map< String,Object > data, String classFullName){
		File file = null ;
		try {
			String fileName = model.getPath();
			PdfReader reader = new PdfReader(fileName);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			/* 将要生成的目标PDF文件名称 */
			PdfStamper ps = new PdfStamper(reader, bos);
			/* 使用中文字体 */
			BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			ArrayList<BaseFont> fontList = new ArrayList <> ();
			fontList.add(bf);

			/* 取出报表模板中的所有字段 */
			AcroFields fields = ps.getAcroFields();
			fields.setSubstitutionFonts(fontList);
			for (String key: data.keySet()) {
				if (data.get(key)!=null) {
					String value = data.get(key).toString();
					fields.setField(key, value);
				}
			}

			/* 必须要调用这个，否则文档不会生成的 */
			ps.setFormFlattening(true);
			ps.close();
			File dir = new File(model.getParent());

			file = File.createTempFile(classFullName.substring(classFullName.lastIndexOf(".")), ".pdf", dir);
			OutputStream fos = new FileOutputStream(file);
			fos.write(bos.toByteArray());
			fos.flush();
			fos.close();
			bos.close();

		}catch (Exception e){
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return file;
	}
}
